package de.fmaul.dicheck;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;

import de.fmaul.dicheck.assertions.AssertionFactory;
import de.fmaul.dicheck.model.Property;
import de.fmaul.dicheck.model.TestContainer;
import de.fmaul.dicheck.provider.LocalScriptTestProvider;
import de.fmaul.dicheck.provider.TestSuiteProvider;
import de.fmaul.dicheck.reporting.FreemarkerReportProvider;
import de.fmaul.dicheck.reporting.ReportProvider;
import de.fmaul.dicheck.reporting.Statistics;
import de.fmaul.dicheck.runner.JdbcTestRunner;
import de.fmaul.dicheck.runner.TestRunner;
import de.fmaul.dicheck.runner.TestRunnerResult;
import de.fmaul.dicheck.util.MailSender;

public class DiCheck {
    private static final String DICHECK_PROPERTIES = "dicheck.properties";
    private static Logger log = Logger.getLogger(DiCheck.class);

    private static Properties readApplicationProperties() {
        final Properties props = new Properties();
        try {
            props.load(new FileInputStream(DICHECK_PROPERTIES));
        } catch (final IOException e) {
            log.warn(DICHECK_PROPERTIES + " not found.");
        }
        return props;
    }

    public static final void main(final String[] args) {

        if (args.length > 0) {

            Properties properties = readApplicationProperties();
            
            final AssertionFactory assertionFactory = new AssertionFactory();

            final TestSuiteProvider tsp = new LocalScriptTestProvider(args[0],
                    properties, assertionFactory);
            final TestRunner runner = new JdbcTestRunner();

            final TestContainer allTests = tsp.getTestSuite();
            final TestRunnerResult result = runner.runTests(allTests);

            final Statistics stats = new Statistics(allTests, result);

            final ReportProvider rp = new FreemarkerReportProvider(properties
                    .getProperty(Property.TEMPLATE_DIRECTORY, "templates"),
                    properties.getProperty(Property.REPORT_OUTPUT_DIRECTORY,
                            "reports"));

            File report = rp.generateReport(allTests, result, stats);
            Statistics.Totals totals = stats.getTotals(allTests.getId());

            Properties props = allTests.getProperties();
            if (Property.getBool(props, Property.MAIL_ENABLED, false)) {
                if (totals.getFailedCount() > 0) {
                    MailSender sender = new MailSender(props);
                    String recipients = props.getProperty(Property.MAIL_TO);
                    log.info("Sending mail about failed reports to "
                            + recipients);
                    sender.send(recipients, "DiCheck failure",
                            "A check has failed. The report is attached.",
                            report);
                }
            }

        } else {
            System.err.println("Please specify a test suite directory.");
        }
    }

}
